package event;

import java.util.ArrayList;

/**
 * This class represents a set of {@link Undoable} operations that must all be undone together.
 * 
 * @author Neil Dickson
 */
public class UndoSet implements Undoable {
	private	ArrayList<Undoable>	undos;
	private	String							description;

	/**
	 * Creates an {@link UndoSet} from an {@link ArrayList} of undoable events.
	 * @param undos			the things to be undone (in the order that they occurred, opposite of order to be undone)
	 * @param description	a description of the event
	 */
	public UndoSet(ArrayList<Undoable> undos,String description) {
		this.undos = undos;
		this.description = description;
	}

	/**
	 * Creates an {@link UndoSet} from an array of undoable events.
	 * @param undos			the things to be undone (in the order that they occurred, opposite of order to be undone)
	 * @param description	a description of the event
	 */
	public UndoSet(Undoable[] undos,String description) {
		ArrayList<Undoable> newUndos = new ArrayList<Undoable>(undos.length);
		for (Undoable u : undos) {
			newUndos.add(u);
		}
		this.undos = newUndos;
		this.description = description;
	}

	/**
	 * This undoes the undos in the order opposite that in which they occurred.
	 * @return the inverse UndoSet; namely, the inverses of the undos provided, but in the opposite order
	 */
	public Undoable undo() {
		ArrayList<Undoable> inverses = new ArrayList<Undoable>(undos.size());
		for (int i=undos.size()-1;i>=0;--i) {
			inverses.add(undos.get(i).undo());
		}
		return new UndoSet(inverses,description);
	}

	/**
	 * @return the description of the event
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * Adds the specified event at the end of the set of undos, (i.e. it occurred most recently)
	 * @param event the {@link Undoable} event to add to the list of undos
	 */
	public void add(Undoable event) {
		undos.add(event);
	}

	/**
	 * @return the number of {@link Undoable}s in this {@link UndoSet}
	 */
	public int size() {
		return undos.size();
	}

	/**
	 * @param i the index
	 * @return the {@link Undoable} at index i in this {@link UndoSet}
	 */
	public Undoable get(int i) {
		return undos.get(i);
	}
}
